package com.fyzk.activity.lottery.jc.beidan;



import java.util.ArrayList;
import java.util.List;

/**
 * 竞彩 注数计算类
 * @author mm
 *
 */
public class BeiDanBetNumUtil {
	
	/**
	 * 自由过关计算注数
	 * @param select  选择 n串1 的n值  例如 2串1 则 select的 值 为2
	 * @param betcodes  每场比赛选择的  个数
	 * @param isDanList   单场比赛 是否被选择为胆码 的Boolean值 的集合
	 * @return 这个串 对应的注数
	 */
	public static long getZhushu(int select,List<Integer> betcodes,List<Boolean> isDanList){
		int isDanNum = getIsDanNum(isDanList);
		return getAllAmt(betcodes, select,isDanList,isDanNum);
	}
	
	/**
	 * 返回总注数竞彩自由过关投注计算注数
	 * 
	 * @param betcodes
	 * @param select
	 * @return
	 */
	public static long getAllAmt(List<Integer> betcodes, int select, List<Boolean> isDanList, int isDanNum) {
		List<int[]> list = goCombine(select, betcodes.size());
		// 返回数据对象
		long resultInt = 0;
		for (int[] result : list) {
			long itemNum = 1;
			int danNum = 0;
			for (int p : result) {
				itemNum *= betcodes.get(p);
				if (isDanNum > 0 && isDanList.get(p)) {
					danNum++;
				}
			}
			if (isDanNum == 0 || danNum == isDanNum) {
				resultInt += itemNum;
			}
		}

		return resultInt;
	}
	
	/**
	 * 多串过关计算注数
	 * @param select
	 * @return
	 */
	public static int getDuoZhushu(int teamNum,int select,List<Boolean> isDanList,List<Integer> betcodes){
		 int isDanNum = getIsDanNum(isDanList);
		return getDouZhushu(teamNum, betcodes, select,isDanList,isDanNum);
	}
	/**
	 * 返回总注数竞彩多串过关投注计算注数
	 * 
	 * @param teamNum
	 *            多串过关3*3 teamNum = 3
	 * @param select
	 *            2*1 select=2
	 * @return 将几场比赛分成几组
	 */
	public static int getDouZhushu(int teamNum, List<Integer> betcodes, int select, List<Boolean> isDanList, int isDanNum) {
		List<int[]> list = goCombine(teamNum, betcodes.size());
		List<int[]> listAll = new ArrayList<int[]>();
		for (int[] resultA : list) {
			// 接收数据
			int[] b = new int[select];
			// 进行组合
			combine(resultA, resultA.length, select, b, select, listAll);
		}
		List<int[]> listNoDiff = new ArrayList<int[]>();
		for(int i=0;i<listAll.size();i++){
			int[] resultA = listAll.get(i);
			if(listNoDiff.size()==0){
				listNoDiff.add(resultA);
			}else{
				int sizeNum = listNoDiff.size();
				for(int j=0;j<sizeNum;j++){
					int[] resultItem = listNoDiff.get(j);
					if(isDiffResult(resultA, resultItem)){
						break;
					}
					if(j==sizeNum-1){
						listNoDiff.add(resultA);
					}
			    }
			}
		}
		int resultInt = 0;
		resultInt = getAllAmtDuo(betcodes,listNoDiff, select, isDanList, 0);

		return resultInt;
	}
	
	/**
	 * 返回总注数竞彩自由过关投注计算注数
	 * 
	 * @param betcodes
	 * @param select
	 * @return
	 */
	public static int getAllAmtDuo(List<Integer> betcodes,List<int[]> list, int select, List<Boolean> isDanList, int isDanNum) {
		// 返回数据对象
		int resultInt = 0;
		for (int[] result : list) {
			int itemNum = 1;
			int danNum = 0;
			for (int p : result) {
				itemNum *= betcodes.get(p);
				if (isDanNum > 0 && isDanList.get(p)) {
					danNum++;
				}
			}
			if (isDanNum == 0 || danNum == isDanNum) {
				resultInt += itemNum;
			}
		}

		return resultInt;
	}
	/**
	 * 两分组是否相同
	 * @param result
	 * @param resultItem
	 * @return
	 */
	private static boolean isDiffResult(int[] result, int[] resultItem) {
		int diffNum = 0;
		 for(int n=0;n<result.length;n++){
			 int nNum = result[n];
			 for(int m=0;m<resultItem.length;m++){
				 int mNum = resultItem[m];
				 if(nNum==mNum){
					 diffNum++;
				 }
			 }
		 }
		 if(diffNum == result.length){
			 return true;
		 }else{
			 return false;
		 }
	}
    /**
     * 进行组合的方法
     * @param teamNum
     * @param listSize
     * @return
     */
	private static List<int[]> goCombine(int teamNum, int listSize) {
		// 初始化原始数据
		int[] a = new int[listSize];
		for (int i = 0; i < a.length; i++) {
			a[i] = i;
		}
		// 接收数据
		int[] b = new int[teamNum];

		List<int[]> list = new ArrayList<int[]>();

		// 进行组合
		combine(a, a.length, teamNum, b, teamNum, list);
		return list;
	}
	
	/**
	 * 获取设胆个数
	 * @return
	 */
	public static int getIsDanNum(List<Boolean> isDanList){
		int num = 0;
		for(int i=0;i<isDanList.size();i++){
			if(isDanList.get(i)){
				num++;
			}
		}
		return num;
	}
	/**
	 * 单关计算注数
	 * @param  betcodes
	 * @return
	 */
	public int getDanZhushu(List<Integer> betcodes){
		return getDanAAmt(betcodes);
	}
	
	/**
	 * 返回总注数竞彩自由过关投注计算注数
	 * 
	 * @param betcodes
	 * @param select
	 * @return
	 */
	public static int getAllAmt(List<Integer> betcodes, int select) {
		List<int[]> list = goCombine(select, betcodes.size());
		// 返回数据对象
		int resultInt = 0;
		for (int[] result : list) {
			int itemNum = 1;
			for (int p : result) {
				itemNum *= betcodes.get(p);
			}
			resultInt+=itemNum;
		}

		return resultInt;
	}
    /**
     * 单关投注计算注数
     * @param betcodes
     * @return
     */
	public static int getDanAAmt(List<Integer> betcodes) {
		int zhushu = 0;
		for (int i = 0; i < betcodes.size(); i++) {
			zhushu += betcodes.get(i);
		}
		return zhushu;
	}

	
	/**
	 * 组合的递归算法
	 * 
	 * @param a
	 *            原始数据
	 * @param n
	 *            原始数据个数
	 * @param m
	 *            选择数据个数
	 * @param b
	 *            存放被选择的数据
	 * @param M
	 *            常量，选择数据个数
	 * @param list
	 *            存放计算结果
	 */
	public static void combine(int a[], int n, int m, int b[], final int M, List<int[]> list) {
		for (int i = n; i >= m; i--) {
			b[m - 1] = i - 1;
			if (m > 1)
				combine(a, i - 1, m - 1, b, M, list);
			else {
				int[] result = new int[M];
				for (int j = M - 1; j >= 0; j--) {
					result[j] = a[b[j]];
				}
				list.add(result);
			}
		}
	}

}
